/******************************************************************************
 *  main.c
 * 	Copyright (C) 2010 - Muhammad Fauzilkamil Zainuddin <jerungkun@gmail.com>
 *  http://coderstalk.blogspot.com 
 * 
 * 	Read piezometer data from serial port (/dev/ttyAM1) 
 *  
 ******************************************************************************/

#include "piezometer.h"  /* piezometer header */
#include "piezodaemon.h" /* piezodaemon header */

/***************************************************************************
* main program                                                             *
***************************************************************************/
int main(int argc, char **argv) {
	int fd, res;
	struct termios oldtio,newtio;	/* definition of terminal IO */
	struct sigaction saio;          /* definition of signal action */
	char buf[255];					/* data buffer */
	char logfilename[180]; 			/* logfile argument variable */
	char portfile[180];				/* serialport argument variable */
	char logdata[255];				/* log data string variable */
	int iflagSetLog=0;				/* Set Log Flag */
	int iflagSetPort=0;				/* Set Port Flag */
	int c;							/* get the getopt character */
    extern char *optarg;			/* getopt argument variable */
	char mytimestr[30];				/* formatted date & time variable */
	struct tm *local;				/* localtime data structure */
	time_t mytime;					/* time variable */
	FILE *f;						/* pid file variable */
	
	/* parse the command arguments */
    while( (c = getopt(argc, argv, "vhL:P:")) != -1) {
        switch(c){
        	case 'v':
        		/* Verbose Mode */
        		iflagVerbose=1; 
        		break;
            case 'h':
            	/* print help */
                PrintUsage(argc, argv);
                exit(0);
                break;
            case 'L':
            	/* set log file name */
            	iflagSetLog=1;
            	strcpy(logfilename,optarg);
                break;
            case 'P':
            	/* set port file name */
            	iflagSetPort=1;
            	strcpy(portfile,optarg);
                break;
            default:
            	/* argv error... print usage */
                PrintUsage(argc, argv);
                exit(0);
                break;
        }
    }

	/* set logfile */    
    if (iflagSetLog == 1) {
    	strcpy(logfile,logfilename);
    } else {
    	/* set the default log file name */
    	sprintf(logfile,"/var/log/pmlog");
    }

	/* set serialfile */    
    if (iflagSetPort == 1) {
    	strcpy(serialfile,portfile);
    } else {
    	/* set the default serial port */
    	sprintf(serialfile,"/dev/ttyAM1");
    }

	/* get current time and put it on log file */
	mytime = time(NULL);
	local = localtime(&mytime);
	strftime(mytimestr,sizeof(mytimestr),"%Y/%m/%d %H:%M:%S",local);
	sprintf(logdata,"[%s] Piezometer Started",mytimestr);
	appendlog(logdata);
	if (iflagVerbose == 1) {
		printf("%s\n",logdata);
	}

	sprintf(logdata,"[%s] Serial Port %s",mytimestr,serialfile);
	appendlog(logdata);
	if (iflagVerbose == 1) {
		printf("%s\n",logdata);
	}

	sprintf(logdata,"[%s] Log File %s",mytimestr,logfile);
	appendlog(logdata);
	if (iflagVerbose == 1) {
		printf("%s\n",logdata);
	}

	/* create pid file */
	if (pid_file) {
		/* open pid file for writing */
		f = fopen(pid_file, "w");
		if (f) {
			/* insert the process ID */
			fprintf(f, "%u\n", getpid());
			fclose(f);
		}
	}

	/* trap all signal to terminate the program */
	signal(SIGHUP, Cleanup);
	signal(SIGINT, Cleanup);
	signal(SIGQUIT, Cleanup);
	signal(SIGTERM, Cleanup);
	signal(SIGKILL, Cleanup);
	
	/* initialize previous minutes to
	 * -1 to ensure the first received value is
	 * sent to server and wait for the next minute */
	prevmin = -1;

	/* open the serial port */		
	fd = open_port(serialfile,iflagVerbose);

	/* install the signal handler before making the device asynchronous */
	memset(&saio, 0, sizeof(saio));
	saio.sa_handler = &signal_handler_IO;
	sigemptyset(&saio.sa_mask);
	saio.sa_flags = 0;
	saio.sa_restorer = NULL;
	sigaction(SIGIO,&saio,NULL);
	  
	/* allow the process to receive SIGIO */
	fcntl(fd, F_SETOWN, getpid());
	/* Make the file descriptor asynchronous (the manual page says only 
	   O_APPEND and O_NONBLOCK, will work with F_SETFL...) */
	fcntl(fd, F_SETFL, FASYNC);
	
	tcgetattr(fd,&oldtio); /* save current port settings */
	/* set new port settings for canonical input processing */
	newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD;
	newtio.c_iflag = IGNPAR;
	newtio.c_oflag = 0;
	newtio.c_lflag = 0; 
	newtio.c_cc[VMIN]=1;
	newtio.c_cc[VTIME]=0;
	tcflush(fd, TCIFLUSH);
	tcsetattr(fd,TCSANOW,&newtio);
	
	/* force to wakeup the piezometer */
	ProcessCommand(fd,"Sleep...");
	
	/* loop while waiting for input. normally we would do something
	   useful here */ 
	while (STOP==FALSE) {
	  //printf(".\n");
	  /* wait for a while */
	  sleep(5);
	  /* after receiving SIGIO, wait_flag = FALSE, input is available
		 and can be read */
	  if (wait_flag==FALSE) { 
	  	sleep(1); // another sleep to wait for input in buffer 
		res = read(fd,buf,255);
		buf[res]=0;
		
		/* process the incoming data buffer */
		ProcessData(fd,buf);
		
		/* wait for new input */
		wait_flag = TRUE;      
	  }
	}
	/* restore old port settings */
	tcsetattr(fd,TCSANOW,&oldtio);
	close(fd);
	return 0;	
}

